package cn.tedu.justone.pack02;

/**
 * @作者：JustOne
 * @时间：2021/8/22 - 15:27
 */
public class Demo08_synchronized修饰普通方法和静态方法 {
    public static void main(String[] args) {

        //synchronized修饰普通方法和静态方法
        //synchronized修饰普通方法和静态方法
        //synchronized修饰普通方法和静态方法

        //相关知识
        // synchronized的三种应用方式
        // 1,修饰实例方法，锁对象是当前实例
        // 2,修饰静态方法，锁对象是当前类对象
        // 3,修饰代码块，锁对象由我们人为规定

        //示例思路：
        //1,先只创建一个Plate实例，测试效果，发现两条线程有互斥效果
        //2,然后创建两个Plate实例，测试效果，发现两条线程没有互斥效果
        //3,分析原因：synchronized修饰实例方法时，锁对象是当前实例，
        //  两条线面对的是不同的锁对象，对对方无效。
        //
        //4,把eatMi()方法改成静态的，测试效果，发现两条线程有互斥效果。
        //5,分析原因：synchronized修饰静态方法，锁对象是当前类对象。
        //  即Plate08.class。一个类，只有一个类对象。

        Plate08 plateA = new Plate08();
        Plate08 plateB = new Plate08();

        Thread girl = new Thread(){
            @Override
            public void run() {
                while (plateA.getMi()>0){
                    plateA.eatMi();
                }
            }
        };

        Thread boy = new Thread(){
            @Override
            public void run() {
                while (plateB.getMi()>0){
                    plateB.eatMi();
                }
            }
        };

        girl.setName("女生");
        boy.setName("男生");

        girl.start();
        boy.start();

    }
}

class Plate08{
    private static int mi = 5;

    public static synchronized void eatMi(){
        if(mi>0){
            mySleep(100);
            System.out.println(Thread.currentThread().getName()+"在吃第"+mi+"颗");
            mi--;
            System.out.println("余数是：" + mi);
        }else{
            System.out.println("已售罄");
        }
    }

    public int getMi(){
        return mi;
    }

    //为了让代码更优雅，编写统一的休眠方法
    public static void mySleep(long m){
        try {
            Thread.sleep(m);
        } catch (InterruptedException e) {
            System.out.println("You：谁喊我？");
            e.printStackTrace();
        }
    }
}
